package useDeprecatedAPI;

import com.google.gson.JsonNull;
import com.google.gson.reflect.TypeToken;
import model.Order;
import model.Product;
import model.User;

import java.lang.reflect.Type;

/*
弃用方法解释：gson2.3
JsonNull()：JsonNull对象构造方法
isAssignableFrom(cls)：检查当前TypeToken是否可以赋值给指定的class类型。
isAssignableFrom(from)：检查当前的 TypeToken 是否可以赋值给指定的type类型。
isAssignableFrom(token)：检查当前TypeToken是否可以赋值给指定的另一个TypeToken对象表示的类型。
 */

/*
调用解释：
引入3个数据模型：Order Product User；currenTypeToken贯穿始终
1.用User初始化currenTypeToken对象
2.用currentTypeToken判断isAssignableFrom(cls)，根据结果更新currentTypeToken对象为Product/Order构造
3.用currentTypeToken判断isAssignableFrom(from)，根据结果再次更新currentTypeToken
4.用currentTypeToken判断isAssignableFrom(token)

整个过程，三个判断函数的结果都会影响currentTypeToken，而currentTypeToken又会影响下面函数的判断结果！
 */
public class TypeTokenAssignmentCheck {

    public static JsonNull jsonNull = null;  // 存储 JsonNull 对象
    // 当前的 TypeToken，以currentTypeToken的变化来实现三个函数之间的依赖
    public TypeToken<?> currentTypeToken = new TypeToken<User>(){};
    public boolean classCheckResult = false;  // 用于存储 isAssignableFromClass 的结果
    public boolean typeCheckResult = false;   // 用于存储 isAssignableFromType 的结果
    public boolean tokenCheckResult = false;  // 用于存储 isAssignableFromToken 的结果

    /**
     * 初始化 JsonNull 对象并执行四个方法的相互依赖。
     */
    public void initializeJsonNullAndCheckAssignable() {
        System.out.println("当前typetoken："+currentTypeToken);
        // 1. 创建 JsonNull 对象
        jsonNull = new JsonNull();
        System.out.println("初始化 JsonNull 对象");

        // 2. 判断 TypeToken 是否可以赋值给 User 类
        classCheckResult = isAssignableFromClass(User.class);
        System.out.println("TypeToken 是否可以赋值给 User.class: " + classCheckResult);

        if (classCheckResult) {
            // 如果可以赋值给 User.class，则更新当前 TypeToken
            currentTypeToken=new TypeToken<Product>(){};
        } else {
            // 如果不能赋值给 User.class，则更新TypeToken
            currentTypeToken=new TypeToken<Order>(){};
        }
        System.out.println("当前typetoken："+currentTypeToken);

        // 3. 使用 isAssignableFrom(from) 判断 TypeToken 是否可以赋值给某个 Type 类型
        Type someType = User.class;  // 假设我们想判断是否可以赋值给 User 类型
        typeCheckResult = isAssignableFromType(someType);
        System.out.println("当前 TypeToken 是否可以赋值给 Type: " + typeCheckResult);

        if (typeCheckResult) {
            // 如果可以赋值给 Type 类型，则更新当前 TypeToken
            currentTypeToken=new TypeToken<Product>(){};
        }else{
            currentTypeToken=new TypeToken<User>(){};
        }

        System.out.println("当前typetoken："+currentTypeToken);

        // 4. 使用 isAssignableFrom(token) 判断当前 TypeToken 是否可以赋值给另一个 TypeToken
        TypeToken<?> anotherToken = new TypeToken<User>() {};  // 创建另一个 TypeToken
        tokenCheckResult = isAssignableFromToken(anotherToken);
        System.out.println("当前 TypeToken 是否可以赋值给另一个 TypeToken: " + tokenCheckResult);

    }

    /**
     * 判断当前 TypeToken 是否可以赋值给指定的 Class 类型。
     */
    public boolean isAssignableFromClass(Class<?> cls) {
        if (jsonNull != null) {
            boolean result = currentTypeToken.isAssignableFrom(cls);
            System.out.println("调用 isAssignableFromClass 方法: " + result);
            classCheckResult = result;

            return result;
        }
        return false;
    }

    /**
     * 判断当前 TypeToken 是否可以赋值给指定的 Type 类型。
     */
    public boolean isAssignableFromType(Type from) {
        if (jsonNull != null) {
            boolean result = currentTypeToken.isAssignableFrom(from);
            System.out.println("调用 isAssignableFromType 方法: " + result);
            typeCheckResult = result;

            return result;
        }
        return false;
    }

    /**
     * 判断当前 TypeToken 是否可以赋值给另一个 TypeToken。
     */
    public boolean isAssignableFromToken(TypeToken<?> token) {
        if (jsonNull != null) {
            boolean result = currentTypeToken.isAssignableFrom(token);
            System.out.println("调用 isAssignableFromToken 方法: " + result);
            tokenCheckResult = result;

            return result;
        }
        return false;
    }

//    /**
//     * 创建一个 TypeToken 对象，表示指定的泛型类型。
//     */
//    public <T> TypeToken<T> createTypeToken(Class<T> clazz) {
//        return new TypeToken<T>() {};  // 创建一个匿名 TypeToken
//    }
}